package com.lsu.app.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lsu.app.bean.*;
import com.lsu.app.config.target.RequestRoles;
import com.lsu.app.service.*;
import com.lsu.app.tool.R;
import com.lsu.app.tool.uploadUtil;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

/**
 * @author hjj
 * @date 2023/10/16 18:56
 */
@RestController
@Slf4j
@CrossOrigin
@RequestMapping("/coms")
public class CommunityController {
    @Value("${web.upload-path}")
    private String uploadPath;
    @Autowired
    private HttpServletRequest request;
    private final UserService userService;
    private final TalkService talkService;
    private final CommentService commentService;
    private final ResourceService resourceService;
    private final LogService logService;
    private final PraiseService praiseService;
    private final CourseService courseService;
    private final KindService kindService;
    private final ClickDateService clickDateService;

    public CommunityController(UserService userService, TalkService talkService, CommentService commentService, ResourceService resourceService, LogService logService, PraiseService praiseService, CourseService courseService, KindService kindService, ClickDateService clickDateService) {
        this.userService = userService;
        this.talkService = talkService;
        this.commentService = commentService;
        this.resourceService = resourceService;
        this.logService = logService;
        this.praiseService = praiseService;
        this.courseService = courseService;
        this.kindService = kindService;
        this.clickDateService = clickDateService;
    }

    @RequestRoles({"teacher","student"})
    @GetMapping("/getTalks")
    @ApiOperation("根据分类标签获取所有话题[分页]")
    public R<Page<Talk>> getTalks(
            @ApiParam("当前页")@RequestParam("pageCur") Integer pageCur,
            @ApiParam("页码")@RequestParam("pageSize") Integer pageSize,
            @ApiParam("类型名称")@RequestParam("typeName") String typeName,
            @ApiParam("排序类型：1最新时间(默认)，2热度（点赞数最高）")@RequestParam("sort") Integer sort
    ){
        LambdaQueryWrapper<Talk> wrapper = new LambdaQueryWrapper<>();
        if(!typeName.equals("")){//标签类型分类
            Integer type = talkService.getTypeIdByTypeName(typeName);
            if(type!=null&&type!=1){
                wrapper.eq(Talk::getType,type);
            }
        }
        if(sort!=null&&sort==2){
            //热度排序
            wrapper.orderByDesc(Talk::getHeat);
        }else{
            //时间排序
           wrapper.orderByDesc(Talk::getCreateTime);
        }
        Page<Talk> talkPage = talkService.page(new Page<>(pageCur,pageSize), wrapper);
        for (Talk talk : talkPage.getRecords()) {
            talk.setHoldName(userService.getNameById(talk.getHoldUserId()));//创建话题者昵称
            talk.setImgUrl(resourceService.getTalkImgsUrlByTalkId(talk.getId()));//话题图片
            talk.setUserUrl(resourceService.getHeadUrlByUorrIdAndType(talk.getHoldUserId()));//设置用户头像
            talk.setResponds(commentService.getCountByTypeAndLinkId(3,talk.getId()));
            talk.setTypeName(talkService.getTypeNameByType(talk.getType()));
            talk.setSelfLike(praiseService.getSelfLike(talk.getId(),5));
        }
        return R.success(talkPage);
    }
    @RequestRoles({"teacher","student"})
    @GetMapping("/search")
    @ApiOperation("根据话题名称大致搜索[分页]")
    public R<Page<Talk>> getPageTalkOfSearch(
            @ApiParam("当前页")@RequestParam("pageCur") Integer pageCur,
            @ApiParam("页码")@RequestParam("pageSize") Integer pageSize,
            @ApiParam("话题名称范围搜索")@RequestParam("titleInfo") String titleInfo
    ){
        LambdaQueryWrapper<Talk> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(Talk::getTitle,"%"+titleInfo+"%");
        Page<Talk> page  = talkService.page(new Page<>(pageCur,pageSize),wrapper);
        for (Talk talk : page.getRecords()) {
            talk.setHoldName(userService.getNameById(talk.getHoldUserId()));//创建话题者昵称
            talk.setImgUrl(resourceService.getTalkImgsUrlByTalkId(talk.getId()));//话题图片
            talk.setUserUrl(resourceService.getHeadUrlByUorrIdAndType(talk.getHoldUserId()));//设置用户头像
            talk.setResponds(commentService.getCountByTypeAndLinkId(3,talk.getId()));
            talk.setTypeName(talkService.getTypeNameByType(talk.getType()));
            talk.setSelfLike(praiseService.getSelfLike(talk.getId(),5));
        }
        return R.success(page);
    }
    @RequestRoles({"teacher","student"})
    @PostMapping("/createTalks")
    @ApiOperation("创建话题[返回的是话题数据]")
    public R<Talk> createTalk(
            @ApiParam("话题标题[128]")@RequestParam("title")String title,
            @ApiParam("话题内容[512]")@RequestParam("content")String content,
            @ApiParam("话题类型")@RequestParam("typeName")String typeName,
            @ApiParam("多张图片一起上传")@RequestParam(value = "imgs",required = false)MultipartFile[] imgs
    ) {
        Integer id = (Integer) request.getSession().getAttribute("id");
        if (!talkService.getAllTypeName().contains(typeName)) {
            typeName = "其他";
        }
        Integer type = talkService.getTypeIdByTypeName(typeName);
        if (type == null) {
            type = 1;
        }
        Talk talk = new Talk(title, content, id, type, LocalDateTime.now().toString());
        //创建话题
        talkService.save(talk);
        if (imgs != null && imgs.length > 0) {
            int err = 0;
            //存入图片
            for (MultipartFile img : imgs) {
                if(img==null||!Objects.requireNonNull(img.getOriginalFilename()).contains(".")||img.isEmpty()){
                    continue;
                }
                String uuid = String.valueOf(UUID.randomUUID());
                R<String> re = uploadUtil.uploadMedia(img, uploadPath + "talks/", uuid);
                if (re.getCode() == 1) {
                    resourceService.save(new Resource(4,talk.getId(), re.getData(), LocalDateTime.now().toString(), LocalDateTime.now().toString()));
                } else {
                    err = 1;
                }
            }
            if (err == 1) {//有图片存入失败，则删除原本数据
                List<Resource> res = resourceService.list(new LambdaQueryWrapper<Resource>().eq(Resource::getType, 4).eq(Resource::getUorrId, id));
                for (Resource resource : res) {
                    uploadUtil.deleteFile(uploadPath + "talks/" + resource.getUrl());
                    resourceService.removeById(resource.getId());
                }
                talkService.removeById(id);
                return R.err("创建失败，稍后再试");
            }
        }
        Talk newTalk = talkService.getById(talk.getId());
        newTalk.setImgUrl(resourceService.getTalkImgsUrlByTalkId(talk.getId()));
        newTalk.setHoldName(userService.getNameById(id));
        newTalk.setUserUrl(resourceService.getHeadUrlByUorrIdAndType(talk.getHoldUserId()));
        newTalk.setResponds(commentService.getCountByTypeAndLinkId(3,newTalk.getId()));
        newTalk.setTypeName(typeName);
        logService.createLog("TALK_CREATE", "create-talk-" + request.getSession().getAttribute("username"), "创建话题");
        return R.success(newTalk);
    }

    @RequestRoles({"teacher","student"})
    @PostMapping("/createCourseTalk")
    @ApiOperation("a创建课程话题")
    public R<Talk> createTalkWithCourse(
            @ApiParam("话题标题[128]")@RequestParam("title")String title,
            @ApiParam("话题内容[512]")@RequestParam("content")String content,
            @ApiParam("课程id")@RequestParam("courseId")Integer courseId,
            @ApiParam("多张图片一起上传")@RequestParam(value = "imgs",required = false)MultipartFile[] imgs
    ) {
        Integer id = (Integer) request.getSession().getAttribute("id");
        if(courseService.getById(courseId)==null){
            return R.err("课程id不存在");
        }
        Talk talk = new Talk(title, content, id, LocalDateTime.now().toString(),1,courseId);
        //创建话题
        talkService.save(talk);
        if (imgs != null && imgs.length > 0) {
            int err = 0;
            //存入图片
            for (MultipartFile img : imgs) {
                if(img==null||!Objects.requireNonNull(img.getOriginalFilename()).contains(".")||img.isEmpty()){
                    continue;
                }
                String uuid = String.valueOf(UUID.randomUUID());
                R<String> re = uploadUtil.uploadMedia(img, uploadPath + "talks/", uuid);
                if (re.getCode() == 1) {
                    resourceService.save(new Resource(4,talk.getId(), re.getData(), LocalDateTime.now().toString(), LocalDateTime.now().toString()));
                } else {
                    err = 1;
                }
            }
            if (err == 1) {//有图片存入失败，则删除原本数据
                List<Resource> res = resourceService.list(new LambdaQueryWrapper<Resource>().eq(Resource::getType, 4).eq(Resource::getUorrId, id));
                for (Resource resource : res) {
                    uploadUtil.deleteFile(uploadPath + "talks/" + resource.getUrl());
                    resourceService.removeById(resource.getId());
                }
                talkService.removeById(id);
                return R.err("创建失败，稍后再试");
            }
        }
        Talk newTalk = talkService.getById(talk.getId());
        newTalk.setImgUrl(resourceService.getTalkImgsUrlByTalkId(talk.getId()));
        newTalk.setHoldName(userService.getNameById(id));
        newTalk.setUserUrl(resourceService.getHeadUrlByUorrIdAndType(talk.getHoldUserId()));
        newTalk.setResponds(commentService.getCountByTypeAndLinkId(3,newTalk.getId()));
        logService.createLog("TALK_CREATE", "create-talk-" + request.getSession().getAttribute("username"), "创建话题");
        return R.success(newTalk);
    }
    @RequestRoles({"teacher","student"})
    @GetMapping("/getCourseTalk")
    @ApiOperation("a获取课程话题")
    public R<CourseWithTalk> getCourseTalk(
        @ApiParam("课程id")@RequestParam("courseId")Integer courseId
    ){
        List<Talk> list = talkService.list(new LambdaQueryWrapper<Talk>().eq(Talk::getCourseId,courseId));
        for (Talk talk : list) {
            talk.setImgUrl(resourceService.getTalkImgsUrlByTalkId(talk.getId()));
            talk.setHoldName(userService.getNameById(talk.getHoldUserId()));
            talk.setUserUrl(resourceService.getHeadUrlByUorrIdAndType(talk.getHoldUserId()));
            talk.setResponds(commentService.getCountByTypeAndLinkId(3,talk.getId()));
            List<Comment> comments = commentService.list(new LambdaQueryWrapper<Comment>().eq(Comment::getType,3).eq(Comment::getLinkId,talk.getId()));
            for (Comment comment : comments) {
                comment.setUserUrl(resourceService.getHeadUrlByUorrIdAndType(comment.getUserId()));
                comment.setNickname(userService.getNameById(comment.getUserId()));
                comment.setSelfLike(praiseService.getSelfLike(comment.getId(),1));
                if(request.getSession().getAttribute("role").equals("teacher")){
                    comment.setUserRole("教师");
                }else{
                    comment.setUserRole("学生");
                }
            }
            talk.setComments(comments);
        }
        Course course = courseService.getById(courseId);
        course.setTeacherName(courseService.getTeacherNameByTeacherId(course.getTeacherId()));
        course.setCoverImgUrl(resourceService.getCoverImgUrlByCourseId(course.getId()));
        course.setResponds(commentService.getCountByTypeAndLinkId(1,course.getId()));
        course.setKindName(kindService.getValueByCourseId(course.getId()));
        course.setSelfLike(praiseService.getSelfLike(course.getId(),3));
        course.setTeacherImgUrl(resourceService.getHeadUrlByUorrIdAndType(course.getTeacherId()));
        return R.success(new CourseWithTalk(list,course,clickDateService.getClickNumOfCourseTalk(courseId)));

    }

    @RequestRoles({"teacher","student"})
    @GetMapping("/getUsers")
    @ApiOperation("搜索用户昵称获取用户组")
    public R<List<User>> getUserBySearchName(
        @ApiParam("昵称")@RequestParam("nickName")String nickName
    ){
        List<User> users = userService.list(new LambdaQueryWrapper<User>().like(User::getName,"%"+nickName+"%"));
        for (User user : users) {
            user.setImageUrl(resourceService.getHeadUrlByUorrIdAndType(user.getId()));
            user.setTaste(userService.getTasteById(user.getId()));
        }
        return R.success(users);
    }
    @RequestRoles({"teacher","student"})
    @GetMapping("/getUserTalks")
    @ApiOperation("获取自己的所有话题")
    public R<Page<Talk>> getTalksByUser(
            @ApiParam("当前页")@RequestParam("pageCur") Integer pageCur,
            @ApiParam("页码")@RequestParam("pageSize") Integer pageSize
    ){
        Page<Talk> talks = talkService.page(new Page<>(pageCur,pageSize),new LambdaQueryWrapper<Talk>().eq(Talk::getHoldUserId,request.getSession().getAttribute("id")));
        for (Talk talk : talks.getRecords()) {
            talk.setHoldName(userService.getNameById(talk.getHoldUserId()));//创建话题者昵称
            talk.setImgUrl(resourceService.getTalkImgsUrlByTalkId(talk.getId()));//话题图片
            talk.setUserUrl(resourceService.getHeadUrlByUorrIdAndType(talk.getHoldUserId()));//设置用户头像
            talk.setResponds(commentService.getCountByTypeAndLinkId(3,talk.getId()));
            talk.setTypeName(talkService.getTypeNameByType(talk.getType()));
            talk.setSelfLike(praiseService.getSelfLike(talk.getId(),5));
        }
        return R.success(talks);

    }

    @RequestRoles({"teacher","student"})
    @GetMapping("/SelfTalks")
    @ApiOperation("用户id获取该用户的所有话题")
    public R<Page<Talk>> getTalksByUser(
        @ApiParam("当前页")@RequestParam("pageCur") Integer pageCur,
        @ApiParam("页码")@RequestParam("pageSize") Integer pageSize,
        @ApiParam("用户id")@RequestParam("userId") Integer userId
    ){
        if(userId!=null){
            Page<Talk> talks = talkService.page(new Page<>(pageCur,pageSize),new LambdaQueryWrapper<Talk>().eq(Talk::getHoldUserId,userId));
            for (Talk talk : talks.getRecords()) {
                talk.setHoldName(userService.getNameById(talk.getHoldUserId()));//创建话题者昵称
                talk.setImgUrl(resourceService.getTalkImgsUrlByTalkId(talk.getId()));//话题图片
                talk.setUserUrl(resourceService.getHeadUrlByUorrIdAndType(talk.getHoldUserId()));//设置用户头像
                talk.setResponds(commentService.getCountByTypeAndLinkId(3,talk.getId()));
                talk.setTypeName(talkService.getTypeNameByType(talk.getType()));
                talk.setSelfLike(praiseService.getSelfLike(talk.getId(),5));
            }
            return R.success(talks);
        }else {
            return R.err("用户错误");
        }
    }


    @RequestRoles({"teacher","student"})
    @DeleteMapping("/deleteTalks")
    @ApiOperation("删除话题")
    public R<String> deleteTalks(
            @ApiParam("话题id")@RequestParam("id")Integer id
    ){
       Talk talk= talkService.getById(id);
       if(talk==null){
           return R.err("话题不存在");
       }
        if(talk.getHoldUserId()==request.getSession().getAttribute("id")){
            if(talkService.removeById(id)){
                List<Resource> res = resourceService.list(new LambdaQueryWrapper<Resource>().eq(Resource::getType,4).eq(Resource::getUorrId,id));
                for (Resource re : res) {
                    //删除话题图片
                    uploadUtil.deleteFile(uploadPath+"talks/"+re.getUrl());
                    //删除资源
                    resourceService.removeById(re.getId());
                }
                talkService.removeById(id);
                praiseService.remove(new LambdaQueryWrapper<Praise>().eq(Praise::getTargetId,id).eq(Praise::getType,5));
                logService.createLog("TALK_DELETE","delete-talk-"+request.getSession().getAttribute("username"),"删除话题");
                return R.success("删除成功");
            }else{
                return R.err("删除失败");
            }
        }else{
            return R.err("无权删除");
        }

    }
    @RequestRoles({"teacher","student"})
    @GetMapping("/getTypes")
    @ApiOperation("获取话题类型标签")
    public R<List<String>> getTalkTypes(){
        return R.success(talkService.getAllTypeName());
    }

    @RequestRoles({"teacher","student"})
    @PostMapping("/createComment")
    @ApiOperation("创建评论")
    public R<Comment> createComment(
        @ApiParam("评论类型(1课程评论，2课程视频评论，3话题评论)")@RequestParam("type")Integer type,
        @ApiParam("关联的课程id/课程视频id/话题id （看type值）")@RequestParam("linkId")Integer linkId,
        @ApiParam("评论内容255")@RequestBody Object content
    ){
        if(type!=1&&type!=2&&type!=3){
            return R.err("类型错误");
        }
        Integer userId = (Integer) request.getSession().getAttribute("id");
        Integer targetId = courseService.getTeacherIdByCourseId(linkId);
        if(type==2){
            targetId=resourceService.getTeacherIdByVideoId(linkId);
        }else if(type==3){
            targetId=talkService.getHostIdByTalkId(linkId);
        }

        Comment comment = new Comment(targetId,type,linkId,userId,(String)content,LocalDateTime.now().toString());
        commentService.save(comment);
        Comment recomment = commentService.getById(comment.getId());
        recomment.setNickname(userService.getNameById(recomment.getUserId()));
        recomment.setUserUrl(resourceService.getHeadUrlByUorrIdAndType(recomment.getUserId()));
        if(request.getSession().getAttribute("role").equals("teacher")){
            recomment.setUserRole("教师");
        }else{
            recomment.setUserRole("学生");
        }
        logService.createLog("COMMENT_CREATE","create-comment-"+request.getSession().getAttribute("username"),"");
        return R.success(recomment);
    }
    @RequestRoles({"teacher","student"})
    @GetMapping("/getComments")
    @ApiOperation("获取资源下的所有评论")
    public R<List<Comment>> getComments(
        @ApiParam("评论类型(1课程评论，2课程视频评论，3话题评论)")@RequestParam("type")Integer type,
        @ApiParam("关联的课程id/课程视频id/话题id （看type值）")@RequestParam("linkId")Integer linkId
    ){
        List<Comment> list = commentService.list(new LambdaQueryWrapper<Comment>().eq(Comment::getType,type).eq(Comment::getLinkId,linkId));
        for (Comment comment : list) {
            comment.setUserUrl(resourceService.getHeadUrlByUorrIdAndType(comment.getUserId()));
            comment.setNickname(userService.getNameById(comment.getUserId()));
            comment.setSelfLike(praiseService.getSelfLike(comment.getId(),1));
            if(userService.isTeacher(comment.getUserId())){
                comment.setUserRole("教师");
            }else{
                comment.setUserRole("学生");
            }
        }
        return R.success(list);
    }
    @RequestRoles({"teacher","student"})
    @GetMapping("/getTalk")
    @ApiOperation("根据id获取获取话题")
    public R<Talk> getTalkById(
            @ApiParam("话题id")@RequestParam("id")Integer id
    ){
        return R.success(talkService.getById(id));
    }

    @RequestRoles({"teacher","student"})
    @DeleteMapping("/delPower")
    @ApiOperation("删除评论（只有创建话题和创建评论的用户可删除）")
    public R<String> getdelPower(
        @ApiParam("评论id")@RequestParam("id")Integer id
    ){
        Comment comment = commentService.getById(id);
        if(comment==null){
            return R.err("评论id不存在");
        }
        Integer userId = (Integer) request.getSession().getAttribute("id");
        if(comment.getUserId()==userId||comment.getTargetUserId()==userId){
            if(commentService.removeById(id)){
                if(comment.getType()==1){
                    praiseService.remove(new LambdaQueryWrapper<Praise>().eq(Praise::getTargetId,id).eq(Praise::getType,1));
                }
                return R.success("删除成功");
            }else{
                return R.err("删除失败，请重试");
            }
        }
        return R.err("无权删除");
    }

    @RequestRoles({"teacher","student"})
    @GetMapping("/getCourTalks")
    @ApiOperation("获取课程话题圈")
    public R<List<CourseWithTalk>> getCourTalks(){
        Integer userId = (Integer) request.getSession().getAttribute("id");
        List<CourseWithTalk> list = new ArrayList<>();
        for (Integer courseId : talkService.getCourseIdsByUserId(userId)) {
            Course course = courseService.getById(courseId);
            course.setTeacherName(courseService.getTeacherNameByTeacherId(course.getTeacherId()));
            course.setCoverImgUrl(resourceService.getCoverImgUrlByCourseId(course.getId()));
            course.setResponds(commentService.getCountByTypeAndLinkId(1,course.getId()));
            course.setKindName(kindService.getValueByCourseId(course.getId()));
            course.setSelfLike(praiseService.getSelfLike(course.getId(),3));
            course.setTeacherImgUrl(resourceService.getHeadUrlByUorrIdAndType(course.getTeacherId()));
            CourseWithTalk cwt = new CourseWithTalk(talkService.getCourseTalksByCourseId(courseId),course,clickDateService.getClickNumOfCourseTalk(courseId));
            list.add(cwt);
        }
        return R.success(list);
    }


}
